/**
 * @Author: 王胜凡
 * @CreateTime: 2022-07-17  16:11
 * @Description: TODO
 * @Version: 1.0
 */
package com.wsf.main.common;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateUtil {
    /**
     * 空串
     */
    private static final String EMPTY_STRING = "";

    /**
     * 常用的时间格式字符串
     */
    public static final String DATE_FORMAT_FULL = "yyyy-MM-dd HH:mm:ss";

    public static final String DATE_FORMAT_YMD = "yyyy-MM-dd";

    public static final String DATE_FORMAT_HMS = "HH:mm:ss";

    public static final String DATE_FORMAT_HM = "HH:mm";

    public static final String DATE_FORMAT_YMDHM = "yyyy-MM-dd HH:mm";
    public static final String DATE_FORMAT_YMDH = "yyyy-MM-dd HH";

    public static final String DATE_FORMAT_YMDHMS = "yyyyMMddHHmmss";

    public static final String DATE_FORMAT_MDHM = "MM-dd HH:mm";

    public static final String DATE_FORMATE_YM = "yyyy-MM";
    public static final String DATE_FORMATE_Y = "yyyy";
    public static final String DATE_FORMAT_YMD_New = "yyyyMMdd";
    public static final String DATE_FORMAT_YMD_New_NOW = "yyMMdd";

    private DateUtil() {
    }

    /**
     * mongo 日期查询isodate
     * <p>
     * <p>
     * 如果相差8小时，加上这句代码
     * format.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT")));
     *
     * @param dateStr
     * @return
     */
    public static Date dateToISODate(String dateStr) {

        Date parse = null;

        try {

            // 解析字符串时间
            Date date = new SimpleDateFormat(DATE_FORMAT_FULL).parse(dateStr);
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
            parse = format.parse(format.format(date));

        } catch (ParseException e) {
            e.printStackTrace();
        }

        return parse;
    }
    /**
     * mongo 日期查询isodate
     * <p>
     * <p>
     * 如果相差8小时，加上这句代码
     * format.setCalendar(new GregorianCalendar(new SimpleTimeZone(0, "GMT")));
     *
     * @param dateStr
     * @return
     */
    public static String dateToISOString(String dateStr) {

        String parse = null;

        try {
            // 解析字符串时间
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSZZ");
            parse =format.format(format.parse(dateStr));


        } catch (ParseException e) {
            e.printStackTrace();
        }

        return parse;
    }
    /**
     * 日期转换为指定格式的字符串
     * <p>当time或format为null时,返回一个空串</p>
     *
     * @param time   时间
     * @param format 格式字符串
     * @return 字符串
     */
    public static String formatDateToString(final Date time, final String format) {
        if (null == time || null == format) {
            return EMPTY_STRING;
        }
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(time);
    }

    /**
     * 日期转换为指定格式的字符串
     * <p>当time或format为null时,返回一个空串</p>
     *
     * @param time   时间
     * @param format 格式字符串
     * @return 字符串
     */
    public static String formatTimestampToString(final Long time, final String format) {
        if (null == time || null == format) {
            return EMPTY_STRING;
        }
        Date date = new Date();
        date.setTime(time);
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    /**
     * 字符串转换为制定格式日期
     *  <p>注意：当你输入的日期是2014-12-21 12:12，format对应的应为yyyy-MM-dd HH:mm
     *    否则异常抛出</p>
     *
     * @param date   时间字符串
     * @param format 转换的时间格式
     * @return 指定格式的日期
     * @throws ParseException 解析时间出现异常
     */
    public static Date formatStringToDate(final String date, final String format) throws ParseException {
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.parse(date);
    }

    /**
     * 判断一个日期是否属于两个时段内
     * <p>注意：时间区间为开区间</p>
     * <p>注意：当参数有空时将返回false</p>
     *
     * @param time      需要判断的时间
     * @param startTime 时间开始范围
     * @param endTime   时间结束范围
     * @return  范围内返回true 否则返回false  
     */
    public static boolean isTimeInRange(final Date time, final Date startTime, final Date endTime) {
        return (time != null && startTime != null && endTime != null)
                && (!time.before(startTime) && !time.after(endTime));
    }

    /**
     * 获取当天是最小时间
     *
     * @return 当天的最小时间
     */
    public static Date getCurDateWithMinTime() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, c.getActualMinimum(Calendar.HOUR_OF_DAY));
        c.set(Calendar.MINUTE, c.getActualMinimum(Calendar.MINUTE));
        c.set(Calendar.SECOND, c.getActualMinimum(Calendar.SECOND));
        c.set(Calendar.MILLISECOND, c.getActualMinimum(Calendar.MILLISECOND));
        return c.getTime();
    }

    /**
     * 获取当天是最大时间
     *
     * @return 当天的最大时间
     */
    public static Date getCurDateWithMaxTime() {
        Calendar c = Calendar.getInstance();
        c.set(Calendar.HOUR_OF_DAY, c.getActualMaximum(Calendar.HOUR_OF_DAY));
        c.set(Calendar.MINUTE, c.getActualMaximum(Calendar.MINUTE));
        c.set(Calendar.SECOND, c.getActualMaximum(Calendar.SECOND));
        c.set(Calendar.MILLISECOND, c.getActualMaximum(Calendar.MILLISECOND));
        return c.getTime();
    }

    /**
     * 获取当天是最小时间的时间戳
     *
     * @return 当天最小时间的时间戳
     */
    public static Long getCurDateTimestampWithMinTime() {
        return getCurDateWithMinTime().getTime();
    }

    /**
     * 获取当天是最大时间的时间戳
     *
     * @return 当天最大时间的时间戳
     */
    public static Long getCurDateTimestampWithMTime() {
        return getCurDateWithMaxTime().getTime();
    }

    /**
     * 根据指定的日期，类型，增加或减少数量
     *
     * @param time          时间
     * @param calendarField 时间的类型
     * @param amount        增加减少的数量
     * @return 时间
     */
    public static Date add(final Date time, final int calendarField, final int amount) {
        if (time == null) {
            return null;
        }
        Calendar c = Calendar.getInstance();
        c.setTime(time);
        c.add(calendarField, amount);
        return c.getTime();
    }

    /**
     * 减去对应的小时
     *
     * @param date 时间
     * @param hour 小时
     * @return date
     */
    public static Date reduceHour(Date date, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, -hour);
        return calendar.getTime();
    }

    /**
     * 减去对应的小时
     *
     * @param date 时间
     * @param hour 小时
     * @return date
     */
    public static Date addHour(Date date, int hour) {
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.HOUR, +hour);
        return calendar.getTime();
    }

    /**
     * 判断两个时间是否在同一个月之内
     *
     * @param time1 时间1
     * @param time2 时间2
     * @return 是否在同一个月
     */
    public static boolean inSameMonth(long time1, long time2) {

        String time1Str1 = formatTimestampToString(time1, DATE_FORMATE_YM);
        String time1Str2 = formatTimestampToString(time2, DATE_FORMATE_YM);

        return time1Str1.equals(time1Str2);

    }
}
